package com.example.components.utils;

import com.example.components.exception.BaseAppException;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.sql.SQLException;
import java.util.Arrays;

/**
 * User: lu
 * Date: 2022/4/21
 * Time: 15:59
 * Version: 1.0
 * Modified By:
 * Description:
 */
public abstract class ExceptionUtil {
    public static final int SQLException_ORA = 1;
    public static final int SQLException_TT = 2;
    public static final int SQLException_ABD = 3;
    public static final int SQLException_QDB = 4;
    public static final int SQLException_ZSMART = 10;
    public static final int SQLException_UNKNOWN = 1000;

    public ExceptionUtil() {
    }

    public static Throwable findMostUsefulInner(Throwable t) {
        if (t == null) {
            return null;
        } else {
            Throwable target = t;

            while (target.getCause() != null) {
                target = target.getCause();
                if (target instanceof Error) {
                    return target;
                }

                if (target instanceof SQLException) {
                    int type = getSQLExceptionVernderType(target);
                    switch (type) {
                        case 1:
                        case 2:
                        case 10:
                            return target;
                    }
                }
            }

            return target;
        }
    }

    public static Throwable getMostInnerException(Throwable t) {
        if (t == null) {
            return null;
        } else {
            Throwable target;
            for (target = t; target.getCause() != null; target = target.getCause()) {
                ;
            }

            return target;
        }
    }

    public static BaseAppException getFirstBaseAppException(Throwable t) {
        for (Throwable cause = t; cause != null; cause = cause.getCause()) {
            if (cause instanceof BaseAppException) {
                return (BaseAppException) cause;
            }
        }

        return null;
    }

    public static Object exCheck(Object arg) {
        if (arg instanceof Throwable) {
            arg = exToString((Throwable) arg);
        }

        return arg;
    }

    public static String exToString(Throwable t) {
        StringWriter sw = new StringWriter(5120);
        PrintWriter pw = new PrintWriter(sw);

        String var3;
        try {
            t.printStackTrace(pw);
            var3 = sw.toString();
        } finally {
            pw.close();
        }

        return var3;
    }

    public static String exToString(Throwable t, int size) {
        String origin = exToString(t);
        return size < origin.getBytes().length ? new String(Arrays.copyOf(origin.getBytes(), size - 3)) + "..." : origin;
    }

    public static int getSQLExceptionVernderType(Throwable t) {
        StackTraceElement[] steList = t.getStackTrace();
        if (steList != null && steList.length > 0) {
            String name = steList[0].getClassName();
            if (name == null) {
                return 1000;
            } else {
                name = name.toLowerCase();
                if (name.startsWith("oracle")) {
                    return 1;
                } else if (name.startsWith("com.timesten")) {
                    return 2;
                } else if (name.startsWith("altibase")) {
                    return 3;
                } else if (name.startsWith("com.ztesoft.zsmart.core.jdbc.qdbdriver")) {
                    return 4;
                } else {
                    return name.startsWith("com.ztesoft") ? 10 : 1000;
                }
            }
        } else {
            return 1000;
        }
    }

    public static BaseAppException getBottomBaseAppException(BaseAppException ex) {
        BaseAppException bottomBaseAppException = ex.getBaseAppException();
        return bottomBaseAppException != null ? getBottomBaseAppException(bottomBaseAppException) : ex;
    }
}